package sources;

import net.rim.device.api.system.Application;
import net.rim.device.api.system.MagnetometerChannelConfig;
import net.rim.device.api.system.MagnetometerData;
import net.rim.device.api.system.MagnetometerSensor;
import net.rim.device.api.system.MagnetometerSensor.Channel;

public class MagnetometerSource extends RandomSource {

	private Channel magnetometerChannel = null;
	private int last = 0;
	
	public String getSourceName() {
		return "Magnetometer Channel";
	}

	protected void generateNext() {
		MagnetometerData data = magnetometerChannel.getData();
		float z = data.getDirectionFront();
		float[] rotationMatrix = new float[4];
		data.getRotationMatrix(rotationMatrix);
		float strength = data.getFieldStrength();
		int bits = getInt(strength, z, rotationMatrix);
		if(bits != last){
			last = bits;
			addToPools(last);
			addRawData(last);
		}
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}



	private int getInt(float strength, float z, float[] rotationMatrix) {
		int b1 = 0xFF & getByte(strength);
		int b2 = 0xFF & getByte(z);
		int b3 = 0xFF & getByte(rotationMatrix[0]);
		int b4 = 0xFF & getByte(rotationMatrix[1]);
		int b5 = 0xFF & getByte(rotationMatrix[2]);
		int b6 = 0xFF & getByte(rotationMatrix[3]);
		return (b1 << 0) | (b2 << 8) | (b3 << 16) | (b4 << 24) ^ (b5 << 20) ^ (b6 << 12);
	}

	private byte getByte(float f) {
		return (byte)getInt(f);
	}

	// Turns, eg 3.283 into the int 283, or
	// 3.283E-5 into 283.
	private int getInt(float f) {
		String str = Float.toString(f);
		str = str.substring(0, str.lastIndexOf('E') == -1 ? str.length() : str.lastIndexOf('E'));
		str = str.substring(str.lastIndexOf('.') + 1);
		return Integer.parseInt(str);
	}

	protected void openResources() {
		MagnetometerChannelConfig mcc = new MagnetometerChannelConfig(/* Update channel every 6.7 ms */150, true, true);
		magnetometerChannel = MagnetometerSensor.openChannel(Application.getApplication(), mcc);
	}

	protected void closeResources() {
		magnetometerChannel.close();
	}

}
